using UnityEngine;
using Prota;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
using Prota.Unity;
using System;
using System.Linq;
using System.Collections.Generic;

namespace Prota.Unity
{
    
    public class ProtaGlobalRenderVariableFeature : ScriptableRendererFeature
    {
        public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
        public bool resetValue;
        public bool cleanUp;
        public MaterialPropertyEntry[] proerties;
        
        
        [NonSerialized] public ProtaGlobalRenderVariablePass pass;
        [NonSerialized] public ProtaGlobalRenderVariableCleanUpPass cleanUpPass;
        
        [NonSerialized] public List<MaterialPropertyEntry> records = new();
        
        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            pass = new ProtaGlobalRenderVariablePass(this);
            cleanUpPass = new ProtaGlobalRenderVariableCleanUpPass(this);
            renderer.EnqueuePass(pass);
            renderer.EnqueuePass(cleanUpPass);
        }

        public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData)
        {
            
        }
        
        public override void Create()
        {
            
        }
        
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }
    }
    
    public class ProtaGlobalRenderVariablePass : ScriptableRenderPass
    {
        ProtaGlobalRenderVariableFeature config;
        
        
        public ProtaGlobalRenderVariablePass(ProtaGlobalRenderVariableFeature x)
        {
            config = x;
            this.renderPassEvent = x.renderPassEvent;
        }
        

        
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if(config.resetValue)
            {
                config.records.Clear();
                foreach(var p in config.proerties.OrEmpty())
                {
                    config.records.Add(p.FetchPropertyGlobally());
                }
            }
            
            using(context.WithCommandBuffer(out var cmd))
            {
                foreach(var p in config.proerties.OrEmpty())
                {
                    p.SetPropertyTo(cmd);
                }
            }
        }

        public override void FrameCleanup(CommandBuffer cmd)
        {
            base.FrameCleanup(cmd);
        }
    }
    
    public class ProtaGlobalRenderVariableCleanUpPass : ScriptableRenderPass
    {
        ProtaGlobalRenderVariableFeature config;
        
        
        public ProtaGlobalRenderVariableCleanUpPass(ProtaGlobalRenderVariableFeature x)
        {
            config = x;
            this.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
        }
        

        
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            using(context.WithCommandBuffer(out var cmd))
            {
                if(config.resetValue && !config.cleanUp)
                {
                    foreach(var p in config.records.OrEmpty())
                    {
                        p.SetPropertyTo(cmd);
                    }
                    config.records.Clear();
                }
                
                if(config.cleanUp)
                {
                    foreach(var p in config.proerties.OrEmpty())
                    {
                        p.UseDefaultValue();
                        p.SetPropertyTo(cmd);
                    }
                }
            }
        }

        public override void FrameCleanup(CommandBuffer cmd)
        {
            base.FrameCleanup(cmd);
        }
    }
}
